using System;

using Styx;

using Styx.CommonBot.Routines;
using Styx.Helpers;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Styx.TreeSharp;
using Action = Styx.TreeSharp.Action;

using CommonBehaviors.Actions;
using Styx.Common;
using Styx.Pathing;


namespace Crusader
{
    partial class Routine : CombatRoutine
    {

        //Current List of supported classes.
        private WoWClass[] classSupport = { WoWClass.Paladin
                                          //  ,WoWClass.Priest
                                          };


        public Version curVersion = new Version(3, 0, 17);

        public override string Name { get { return "Crusader v" + curVersion; } }
        public override WoWClass Class
        {
            get
            {
                foreach (WoWClass c in classSupport)
                {
                    if (Me.Class.Equals(c))
                        return c;
                }

                return WoWClass.Paladin;
            }
        }

        public override bool WantButton {get {return true;}}

        private frmSettings SettingsWindow = null;

        public override void OnButtonPress()
        {
            if(SettingsWindow ==null || SettingsWindow.IsDisposed)
                SettingsWindow = new frmSettings();
            SettingsWindow.Show();
            SettingsWindow.Focus();
        }

        private static LocalPlayer Me { get { return StyxWoW.Me; } }

        public override void Initialize()
        {
            Logging.Write("");
            Logging.Write(Name + " is now operational.");
            Logging.Write("");
            Logging.Write("You are a level {0} {1} {2} {3}.", Me.Level, Me.Race, Me.Specialization.ToString(), Me.Class);
            Logging.Write("");
            Logging.Write("Building Behavior Tree.");
        }

        #region Composite declarations

        /* Composites seem to have the following priority order: 
         *    Rest
         *    PreCombatBuff
         *    Pull
         *    Heal
         *    CombatBuff
         *    Combat
         *    
         * This implies that each composite we override is equivalent to 
         * a node in a PrioritySelector.
         * 
         * e.g.: if Rest returns RunStatus.Success to the tree-walker, no
         * other overrides are visited. 
         * 
         * If the player is in combat, only Heal, CombatBuff, and Combat
         * are visited by the tree-walker.
         */

        private Composite _CombatBehavior;
        private Composite _PullBehavior;
        private Composite _MoveToTargetBehavior;

        private Composite _CombatBuffBehavior;
        private Composite _PreCombatBuffBehavior;

        private Composite _RestBehavior;
        private Composite _HealBehavior;

        public override Composite CombatBehavior
        {
            get
            {
                if (_CombatBehavior == null)
                {

                    _CombatBehavior = new PrioritySelector(

                            //Extra stuff before rotation.
                            UseLightwell(),
                            UseHealthstone(),

                            //Interupt Spells.
                            CheckForInterupts(),

                            StopRotation(),

                            ValidUnitCheck(),

                            //Reaaaaly basic movement code.
                            //new Decorator( ret => Me.CurrentTarget !=null && ValidUnit(Me.CurrentTarget), new Action( ret=> Me.Face())),
                            //new Decorator( ret => Me.CurrentTarget !=null && ValidUnit(Me.CurrentTarget) && Me.CurrentTarget.Distance > 2,
                            //    new Action(ret => Navigator.MoveTo(Me.CurrentTarget.Location))),
                            //new Decorator( ret => Me.CurrentTarget !=null && ValidUnit(Me.CurrentTarget) && Me.CurrentTarget.Distance <= 2, new Action(ret => Navigator.PlayerMover.MoveStop())),
                        
                            //Combat rotations
                            new Decorator(ret => Me.Specialization == WoWSpec.PaladinProtection,
                                Crusader.Routine.Paladin.ProtectionCombatBehavior()
                            ),

                            new Decorator(ret => Me.Specialization == WoWSpec.PaladinRetribution,
                                 Crusader.Routine.Paladin.RetributionCombatBehavior()
                            ),

                            new Decorator(ret => Me.Specialization == WoWSpec.PaladinHoly,
                                 Crusader.Routine.Paladin.HolyCombatBehavior()
                            )

                        );
                    Logging.Write("  Combat behavior built (currently, {0})", Me.Specialization.ToString());
                }

                return _CombatBehavior;
            }
        }

        public override Composite PullBehavior
        {
            get
            {
                if (_PullBehavior == null)
                {
                    Logging.Write("  Pull behavior built");

                    _PullBehavior = new Action();
                }

                return _PullBehavior;
            }
        }

        public override Composite MoveToTargetBehavior
        {
            get
            {
                if (_MoveToTargetBehavior == null)
                {
                    Logging.Write("  MoveToTarget behavior built");

                    _MoveToTargetBehavior = new Action();
                }

                return _MoveToTargetBehavior;
            }
        }

        public override Composite CombatBuffBehavior
        {
            get
            {
                if (_CombatBuffBehavior == null)
                {
                    _CombatBuffBehavior = new PrioritySelector(
                            
                            new Decorator(ret => !Me.IsAlive || Me.Mounted,
                                new ActionIdle ()),

                            new Decorator(ret => (Me.Class.Equals(WoWClass.Paladin)),
                                Crusader.Routine.Paladin.CombatBuffBehavior())
                        );
                }

                return _CombatBuffBehavior;
            }
        }

        public override Composite PreCombatBuffBehavior
        {
            get
            {
                if (_PreCombatBuffBehavior == null)
                {
                    _PreCombatBuffBehavior = new PrioritySelector(

                            new Decorator(ret => !Me.IsAlive || Me.Mounted,
                                new ActionIdle()),

                            new Decorator(ret => (Me.Class.Equals(WoWClass.Paladin)),
                                Crusader.Routine.Paladin.PreCombatBuffBehavior())
                                
                        );
                }

                return _PreCombatBuffBehavior;
            }
        }

        public override Composite RestBehavior
        {
            get
            {
                if (_RestBehavior == null)
                {
                    Logging.Write("  Rest behavior built");

                    _RestBehavior = new Action();
                }

                return _RestBehavior;
            }
        }

        public override Composite HealBehavior
        {
            get
            {
                if (_HealBehavior == null)
                {
                    Logging.Write("  Heal behavior built");

                    _HealBehavior = new Action();
                }

                return _HealBehavior;
            }
        }

        #endregion
    }
}